package com.zcf.gameController.gameUtils;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.zcf.gameController.F_Websocket_s;
import com.zcf.pojo.Msg;
import com.zcf.pojo.RoomsParam;
import com.zcf.pojo.UserBean;
import org.springframework.beans.BeanUtils;

import javax.websocket.Session;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @author ： jj
 * @date ：2019/11/20 9:29
 * @description :
 * @path : SgOpenCardsTimer.java.SgOpenCardsTimer
 */
public class SgOpenCardsTimer extends Thread{
	private Gson gson = new GsonBuilder() .setExclusionStrategies(new ExclusionStrategy() {
		@Override
		public boolean shouldSkipField(FieldAttributes f) {
			return false;
		}
		@Override
		public boolean shouldSkipClass(Class<?> incomingClass) {
			return incomingClass == Session.class;
		}
	}) .create();
	/**
	 * 牌型
	 */
	SgHandPattern px=new SgHandPattern();

	private  Integer timer;

	private RoomsParam myRoom;

	private F_Websocket_s ws;
	private Map<String, Object> data = new HashMap<>();
	public SgOpenCardsTimer(Integer timer, RoomsParam myRoom, F_Websocket_s ws){
		this.timer = timer;
		this.ws = ws;
		this.myRoom = myRoom;
	}
	@Override
	public void run() {
		while (timer >0 ) {
			if ( Thread.currentThread().isInterrupted() ) {
				System.out.println("线程终止");
				break;
			}
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("亮牌倒计时"+timer);
			timer --;
			myRoom.setTimer(timer);
			List<UserBean> userBeans =myRoom.getUsers().values().stream().filter(userBean->userBean.getIsReady().equals(1)).collect(Collectors.toList());
			Map<Integer, List<UserBean>> collect = userBeans.stream().collect(Collectors.groupingBy(UserBean::getOpenCards));
			int a=0;
			if (collect.get(1)!=null){
				a=collect.get(1).size();
			}
			System.out.println("在座人数:"+userBeans.size()+"亮牌人数:"+a);
			if (userBeans.size()==a){
				timer=0;
			}
			if(timer <= 0){
				data.put("cards", myRoom.getCards());
				data.put("bunko",myRoom.getBunko());
				data.put("personal" , 1);
				data.put("isStart" , myRoom.getIsStart());
				Msg msg = new Msg(200,"亮牌", data,"openCard");
				try {
					ws.broadcast(msg, myRoom);
				} catch (Exception e) {
					e.printStackTrace();
				}
				myRoom.setIsStart(6);
				Map<Integer, Integer> betMoeny = myRoom.getBetMoeny();
				Map<Integer, Integer> betMoeny1 = new HashMap<> (betMoeny);
				//结算
				if ( myRoom.getIsUp()!=0) {
					village();
					UserBean userBean = myRoom.getUserBean(myRoom.getIsUp());
					if (userBean.getSumWinnumber()>0){
						userBean.setSumWinnumber(userBean.getSumWinnumber()-(int) (userBean.getSumWinnumber()*myRoom.getPumping()));
					}
					userBean.setMoney(userBean.getMoney()+userBean.getSumWinnumber());


				}else {
					notVillage(betMoeny,betMoeny1);
					for (Integer id:betMoeny.keySet()){
						betMoeny1.put(id,betMoeny.get(id)-betMoeny1.get(id));
					}
				}
				if (myRoom.getIsUp()!=0){
					for (Integer i:myRoom.getBunko().keySet()){
						if (myRoom.getBunko().get(i)>0){
							betMoeny1.put(i,betMoeny1.get(i)-(int)(betMoeny1.get(i)*myRoom.getPumping()));
						}
					}
				}else {
					for (Integer i:myRoom.getBunko().keySet()){
						if (betMoeny1.get(i)>0){
							betMoeny1.put(i,betMoeny1.get(i)-(int)(betMoeny1.get(i)*myRoom.getPumping()));
						}
					}
				}

				try {
					Thread.sleep(3000);
				}catch (Exception e){
					e.printStackTrace();
				}
				data.clear();
				data.put("users",userBeans);
				data.put("betMoney",betMoeny1);
				data.put("bunko",myRoom.getBunko());
				data.put("cards",myRoom.getCards());
				data.put("isStart" , myRoom.getIsStart());
				data.put("isUp",myRoom.getIsUp());
				data.put("positions",myRoom.getPostions());
				Msg ms = new Msg(200,"结算", data,"balance");
				try {
					ws.broadcast(ms, myRoom);
				} catch (Exception e) {
					e.printStackTrace();
				}
				for (UserBean us:myRoom.getUsers().values()){
					data.clear();
					data.put("money",us.getMoney());
					data.put("sumWinnumber",us.getSumWinnumber());
					Msg ms1 = new Msg(200,"结算", data,"userBalance");
					try {
						ws.broadcastMe(ms1, us.getSession(),us);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				List<UserBean> users = new ArrayList<>();
				for (UserBean userBean:myRoom.getUsers().values()){
					UserBean u2=new UserBean();
					BeanUtils.copyProperties(userBean,u2);
					users.add(u2);
				}
				AccountThread accountThread=new AccountThread(users,myRoom.getRoomGrade(),myRoom.getRoomName(),myRoom.getPumping(),myRoom.getGametype());
				accountThread.start();
				System.out.println("--------------------------开始下一轮-------------------------------");
				myRoom.setIsStart(0);
				myRoom.clear();
				List<UserBean> mRoom=new ArrayList<>(myRoom.getUsers().values());
				for (UserBean ur:mRoom){
					if (ur.getType()==3){
                        if (myRoom.getPostions().contains(ur.getId().intValue())){
                            int i1 = myRoom.getPostions().indexOf(ur.getId().intValue());
                            myRoom.getPostions().set(i1,0);
                        }
                        ur.setPosition(-1);
						myRoom.getUsers().remove(ur.getId().toString());
					}
				}
				data.clear();
				UserBean userBean = myRoom.getUserBean(myRoom.getIsUp());
				if (userBean!=null){
					if (userBean.getIsOwner()==4){
						data.put("isOwner",userBean.getId());
					}else {
						data.put("isOwner",0);
					}
				}else {
					data.put("isOwner",0);
				}
				myRoom.setIsUp(0L);
				try {
					List<UserBean> userBeanList =myRoom.getUsers().values().stream().filter(userBean1->userBean1.getType().equals(1)).collect(Collectors.toList());
					data.put("isStart" , myRoom.getIsStart());
					data.put("users" , userBeanList);
					data.put("positions" , myRoom.getPostions());
					Msg m=new Msg(200,"开启下一轮",data,"round");
					ws.broadcast(m,myRoom);
				} catch (Exception e) {
					e.printStackTrace();
				}

			}
		}
	}


	/**
	 * @description :有庄结算
	 * @date : 2019/11/21 10:43
	 * @author : jj
	 */
	private void village(){
		int zSum=0;
		int xSum=0;
		Map<Integer, List<Integer>> cardsMap = myRoom.getCards();
		Integer banker = myRoom.getIsUp().intValue();
		Integer up = myRoom.getPostions().indexOf(banker);
		List<Integer> bankerCards = cardsMap.get(up);
		zSum = px.algorithm(bankerCards);
		data.put("zpai",zSum);
		for (Integer position : cardsMap.keySet()) {
			if (position.equals(banker)) {
				continue;
			}
			xSum = px.algorithm(cardsMap.get(position));
			if (zSum >= xSum) {
				myRoom.getBunko().put(position, 1);
			} else {
				myRoom.getBunko().put(position, 0);
			}
			if (zSum >3000 && xSum>3000) {
					myRoom.getBunko().put(position, 0);

			}
		}
		//结算金币
		UserBean zUser=myRoom.getUsers().get(myRoom.getIsUp()+"");
		for (String userid:myRoom.getUsers().keySet()){
			if (userid.equals(myRoom.getIsUp()+"")){
				continue;
			}
			UserBean userBean = myRoom.getUsers().get(userid);
			for (Integer positions:userBean.getBetList().keySet()){
				if (positions.equals(zUser.getPosition())){
					continue;
				}
				Integer bunko = myRoom.getBunko().get(positions);
				Integer betMoney = userBean.getBetList().get(positions);
				if (bunko==1){
					userBean.setSumWinnumber(userBean.getSumWinnumber()+betMoney);
					zUser.setSumWinnumber(zUser.getSumWinnumber()-betMoney);
				}else {
					userBean.setSumWinnumber(userBean.getSumWinnumber()-betMoney);
					zUser.setSumWinnumber(zUser.getSumWinnumber()+betMoney);
				}
			}

			if (userBean.getSumWinnumber()>0){
				int sumWinnumber = userBean.getSumWinnumber();
				userBean.setSumWinnumber(userBean.getSumWinnumber()-(int) (userBean.getSumWinnumber() *myRoom.getPumping()));
				userBean.setMoney(userBean.getMoney()+sumWinnumber*2-(int) (userBean.getSumWinnumber() *myRoom.getPumping()));
			}

		}
	}
	
	/**
	* @description :无庄结算
	* @date : 2019/11/21 10:43
	* @author : jj
	*/
	private void  notVillage(Map<Integer, Integer> betMoeny,Map<Integer, Integer> betMoeny1){
		List<Integer> list =null;
		HashMap <Integer,Integer> sum=new HashMap<>();
		//排序
		List<Integer> sorting = sorting(list, sum);
		bgm:for (int i =0;i<sorting.size() ; i++){
			int index = sum.get(sorting.get(i));
			int money = betMoeny.get(index);
			int meta=0;
			t2:for (int j= sorting.size()-1; j >=0 ;j--){
				int index1 = sum.get(sorting.get(j));
				int money1 = betMoeny.get(index1);
				int sumMoney = betMoeny1.get(index)*2;
				if (money==sumMoney){
					continue ;
				}
				if(money1==0){
					continue;
				}
				if (index==index1){
					break bgm;
				}
				if ((money1-money)>=0){
					int money3=money1-money;
					betMoeny.put(index,money*2);
					betMoeny.put(index1,money3);
					break;
				}else {
					for (int m =j ; m >=0;m--){
						Integer money4 = betMoeny.get(index);
						Integer index2 = sum.get(sorting.get(m));
						Integer money2 = betMoeny.get(index2);
						if (money4==sumMoney){
							break t2;
						}
						if (money4+money2>sumMoney){
							Integer money3= sumMoney-money4;
							betMoeny.put(index,sumMoney);
							betMoeny.put(index2,money3);
						}else {
							Integer money3=money4+money2;
							betMoeny.put(index,money3);
							betMoeny.put(index2,0);
						}
					}
				}
			}
		}
		for (String userid:myRoom.getUsers().keySet()){
			if (userid.equals(myRoom.getIsUp()+"")){
				continue;
			}
			UserBean userBean = myRoom.getUsers().get(userid);
			int number=0;
			for (Integer positions:userBean.getBetList().keySet()){
				if (betMoeny1.get(positions)*2==betMoeny.get(positions)){
					Integer userBetMoney = userBean.getBetList().get(positions);
					number+=(int)(userBetMoney-userBetMoney*myRoom.getPumping());
					userBean.setSumWinnumber(userBean.getSumWinnumber()+userBetMoney);
				}else if (betMoeny1.get(positions)*2<betMoeny.get(positions)&&betMoeny.get(positions)>betMoeny1.get(positions)){
					Integer userBetMoney = userBean.getBetList().get(positions);
					double ratio= userBetMoney/betMoeny1.get(positions);
					double jg = betMoeny.get(positions) * ratio;
					userBean.setSumWinnumber(userBean.getSumWinnumber()+(int)jg);
					number+=(int)(jg-jg*myRoom.getPumping());
				}else if (betMoeny.get(positions)<betMoeny1.get(positions)) {
					Integer userBetMoney = userBean.getBetList().get(positions);
					double ratio= userBetMoney/betMoeny1.get(positions);
					double jg = betMoeny.get(positions) * ratio;
					if ((int) jg==0){
						number=number-userBetMoney;
					}else {
						number=number-(userBetMoney-(int)jg);
					}
				}
			}
			if (userBean.getSumWinnumber()>0){
				int sumWinnumber = userBean.getSumWinnumber();
				userBean.setSumWinnumber(userBean.getSumWinnumber()-(int) (userBean.getSumWinnumber() *myRoom.getPumping()));
				userBean.setMoney(userBean.getMoney()+sumWinnumber*2-(int) (userBean.getSumWinnumber() *myRoom.getPumping()));
			}
			userBean.setTotal(number);
		}
	}

	/**
	* @description :排序
	* @param list 
	* @param sum
	* @date : 2019/11/21 12:15
	* @author : jj
	*/
	private  List<Integer>  sorting(List<Integer> list,HashMap <Integer,Integer> sum){
		Map<Integer, List<Integer>> cardsMap = myRoom.getCards();
		int xSum=0;
		for (Integer position : cardsMap.keySet()) {
			xSum = px.algorithm(cardsMap.get(position));
			sum.put(xSum,position);
		}
		list = new ArrayList<> (sum.keySet());
		for(int i=0;i<list.size();i++) {
			for(int j=0;j<list.size()-1-i;j++)
			{
				if(list.get(j)>list.get(j+1))
				{
					int temp=list.get(j);
					list.set(j,list.get(j+1));
					list.set(j+1,temp);
				}
			}
		}
		for (int s = 0; s < list.size(); s++){
			Integer index = sum.get(list.get(s));
			myRoom.getBunko().put(index, s);
		}
		return list;
	}
}
